﻿using System;
using System.Collections.Generic;
using System.Text;
using UtilZ.Dotnet.Ex.Base;
using UtilZ.Dotnet.Ex.Communication.Base;
using UtilZ.Dotnet.Ex.Communication.Net.Base;

namespace UtilZ.Dotnet.Ex.Communication.Net.BMQ
{
    /// <summary>
    /// BMQ-TCP-TLV分包器
    /// </summary>
    public class BMQTcpTLVUnpacker : UnpackerAbs
    {
        /************************************************
         * 字段   数据类型    大小(byte)  说明
         * T      byte        1           Tag
         * L      Int32       4           Length
         * V      byte[]      L指定长度   Value
         ************************************************/



        /// <summary>
        /// 构造函数
        /// </summary>
        public BMQTcpTLVUnpacker()
        {

        }



        /// <summary>
        /// 对数据进行拆包
        /// </summary>
        /// <param name="unpackerPara">分包参数</param>
        /// <returns>拆包成功的数据长度</returns>
        protected override int PrimitiveUnPackge(IUnpackerPara unpackerPara)
        {
            var np = (TcpUnpackerPara)unpackerPara;
            if (np.DataLength == 0)
            {
                return 0;
            }

            var reader = np.Reader;
            long parseBeginPosition = reader.BaseStream.Position;
            long currentParseBeginPosition = parseBeginPosition;
            long parseEndPosition = parseBeginPosition + np.DataLength;
            int parseDataLength = 0;

            //至少需要6个字节才够头
            if (parseEndPosition - currentParseBeginPosition < BMQConstant.TLV_HEAD_MIN_SIZE)
            {
                return parseDataLength;
            }

            while (reader.BaseStream.Position < parseEndPosition &&
               parseEndPosition - reader.BaseStream.Position > BMQConstant.TLV_HEAD_MIN_SIZE)
            {
                byte tag = reader.ReadByte();
                int length = reader.ReadInt32();
                if (parseEndPosition - reader.BaseStream.Position < length)
                {
                    //数据未接收全，下次再解析
                    break;
                }

                //将接收到的数据组包成与UDP的一致，便于后续处理
                byte[] dataBuffer = new byte[length];
                reader.Read(dataBuffer, 0, length);
                currentParseBeginPosition = reader.BaseStream.Position;
                var args = new DataOutputArgs(unpackerPara.LinkInfo, new Model.BufferData(dataBuffer, 0, dataBuffer.Length));
                base.OnRaiseOnReceivedData(np.Client, args);
            }

            parseDataLength = (int)(currentParseBeginPosition - parseBeginPosition);

            if (reader.BaseStream.Position != currentParseBeginPosition)
            {
                reader.BaseStream.Position = currentParseBeginPosition;
            }

            return parseDataLength;
        }
    }

}
